const { Controller } = require("egg");

class UserController extends Controller {
  // 注册
  async create() {
    const {
      ctx: {
        request: { body },
        service: { user: userService },
      },
    } = this;

    this.ctx.validate({
      username: { type: "string" },
      email: { type: "email" },
      password: { type: "string" },
    });

    if (await userService.findByUsername(body.username)) {
      this.ctx.throw(422, "用户已存在");
    }
    if (await userService.findByEmail(body.email)) {
      this.ctx.throw(422, "邮箱已存在");
    }
    const user = await userService.createUser(body);
    const token = userService.createToken({
      userId: user._id,
    });

    this.ctx.body = {
      email: user.email,
      token,
      username: user.username,
      channelDescription: user.channelDescription,
      avatar: user.avatar,
    };
  }

  // 登录
  async login() {
    const { ctx } = this;
    const {
      request: { body },
      service: { user: userService },
      helper,
    } = this.ctx;

    ctx.validate({
      email: { type: "email" },
      password: { type: "string" },
    });

    const user = await userService.findByEmail(body.email);
    if (!user) {
      ctx.throw(401, "用户不存在");
    }

    if (helper.md5(body.password) !== user.password) {
      ctx.throw(401, "密码错误");
    }

    const token = userService.createToken({
      userId: user._id,
    });

    ctx.body = {
      email: user.email,
      token,
      username: user.username,
      channelDescription: user.channelDescription,
      avatar: user.avatar,
    };
  }

  // 获取当前登录用户消息
  async getCurrentUser() {
    const { ctx } = this;
    const { user } = ctx;
    ctx.body = {
      email: user.email,
      token: ctx.header["authorization"],
      username: user.username,
      channelDescription: user.channelDescription,
      avatar: user.avatar,
    };
  }

  // 更新用户
  async update() {
    const { ctx } = this;
    const {
      request: { body },
      service: { user: userService },
      user,
    } = this.ctx;

    ctx.validate(
      {
        email: { type: "email", required: false },
        password: { type: "string", required: false },
        username: { type: "string", required: false },
        channelDescription: { type: "string", required: false },
        avatar: { type: "string", required: false },
      },
      body
    );

    // 不能修改当前登录的用户，并且不能修改也存在的email
    if (body.user.email) {
      if (
        body.user.email !== user.email &&
        (await userService.findByEmail(body.email))
      ) {
        ctx.throw(422, "邮箱已存在");
      }
    }

    // 不能修改当前登录的用户，并且不能修改已经存在的username
    if (body.user.username) {
      if (
        body.user.username !== user.username &&
        (await userService.findByUsername(body.email))
      ) {
        ctx.throw(422, "用户已存在");
      }
    }

    if (body.user.password) {
      body.user.password = ctx.helper.md5(body.user.password);
    }

    const userData = await userService.updateUser(body.user);
    ctx.body = {
      email: userData.email,
      username: userData.username,
      channelDescription: userData.channelDescription,
      avatar: userData.avatar,
    };
  }

  // 订阅
  async subscribe() {
    const {
      ctx: {
        helper,
        service: { user: userService },
        user: { _id: userId },
        params: { userId: channelId },
      },
    } = this;

    // 1. 用户不能订阅自己
    if (userId.equals(channelId)) {
      this.ctx.throw(403, "不能订阅自己");
    }

    // 2. 添加订阅
    const user = await userService.subscribe(userId, channelId);
    this.ctx.body = {
      // ...user.toJSON(),
      ...helper._.pick(user, [
        "username",
        "email",
        "avatar",
        "cover",
        "channelDescription",
        "subscribersCount",
      ]),
      isSubscribed: true,
    };
  }

  // 取消订阅
  async unsubscribe() {
    const { ctx } = this;
    const {
      service: { user: userService },
      helper,
      user: { _id: userId },
      params: { userId: channelId },
    } = this.ctx;

    // 1. 用户不能订阅自己
    if (userId.equals(channelId)) {
      ctx.throw(403, "不能订阅自己");
    }

    // 2. 添加订阅
    const user = await userService.unsubscribe(userId, channelId);
    ctx.body = {
      ...helper._.pick(user, [
        "username",
        "email",
        "avatar",
        "cover",
        "channelDescription",
        "subscribersCount",
      ]),
      isSubscribed: false,
    };
  }

  // 用户消息
  async getUser() {
    const {
      ctx: { helper, params, user },
      app: {
        model: { Subscription, User },
      },
    } = this;
    // 1. 获取订阅状态
    let isSubscribed = false;
    if (user) {
      // 获取订阅记录
      const record = await Subscription.findOne({
        userId: user._id,
        channelId: params.userId,
      });
      isSubscribed = record ? true : false;
    }
    // 2. 获取用户信息
    const userData = await User.findById(params.userId);
    // 3. 返回用户信息
    this.ctx.body = {
      ...helper._.pick(userData, [
        "username",
        "email",
        "avatar",
        "cover",
        "channelDescription",
        "subscribersCount",
      ]),
      isSubscribed,
    };
  }

  // 订阅详情
  async getSubscriptions() {
    const {
      ctx: { helper, params },
      app: {
        model: { Subscription },
      },
    } = this;

    let subscriptions = await Subscription.find({
      user: params.userId,
    }).populate("channel");

    subscriptions = subscriptions.map((item) => {
      return helper._.pick(item.channel, ["_id", "username", "avatar"]);
    });

    this.ctx.body = {
      subscriptions,
    };
  }
}

module.exports = UserController;
